<?php
/**
 * 
 * @package qBase
 * @subpackage sql
 */

/**
 * Enter description here...
 * @package qBase
 * @subpackage sql
 */
final class QSql extends QObject 
{
	/**
	 * The list of connection added to the application
	 *
	 * @var array
	 */
	private static $Connections = array();
	/**
	 * The default SQL connection
	 *
	 * @var QSqlConnection
	 */
	private static $DefaultConnection = null;
	/**
	 * The default connection's tag
	 *
	 */
	const DefaultTag = "default";
	
	/**
	 * Sets a connection 
	 *
	 * @param string $tag
	 * @param integer $type
	 * @param string $host
	 * @param integer $port
	 * @param string $user
	 * @param string $pass
	 * @param string $db
	 */
	public static function SetConnection($tag, $type, $host, $port, $user, $pass, $db = null)
	{
		if ((!$tag) || (!is_string($tag)))
		{
			throw new Exception("QSql::SetConnection the tag must be a valid string");
		}
		
		$sql_connection = null;
		if ($type == QSqlConnection::TypeMySql)
		{
			$sql_connection = new QMySqlConnection($host, $port, $user, $pass, $db, $type);
			self::$Connections[$tag] = $sql_connection;
		}
		else 
		{
			throw new Exception("QSql::SetConnection unknown type $type");
		}
		
		if ($tag == self::DefaultTag)
		{
			self::$DefaultConnection = $sql_connection;
		}
	}
	
	/**
	 * Gets an Sql connection by tag
	 *
	 * @param string $tag
	 * @return QSqlConnection
	 */
	public static function GetConnection($tag = self::DefaultTag)
	{
		if (self::$Connections[$tag])
			return self::$Connections[$tag];
		else 
			return null;
	}
	
	/**
	 * Connects to the database
	 * 
	 * @param string $connection_tag the tag to use when connecting to the database
	 *
	 */
	public static function Connect($connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		self::GetConnection($connection_tag)->connect();
	}
	/**
	 * Closes the connection to the database
	 * 
	 * @param string $connection_tag
	 *
	 */
	public static function Close($connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		self::GetConnection($connection_tag)->close();
	}
	/**
	 * Executes a query
	 *
	 * @param string $query
	 * @param string $connection_tag
	 * @return returns a link to the result set
	 */
	public static function Query($query, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		return self::GetConnection($connection_tag)->query($query);
	}
	
	/**
	 * Gets only the first row from a query. LIMIT must be specified in query if it's desired
	 * Returns null if the first row does not exist
	 *
	 * @param string $query
	 * @param string $connection_tag
	 * @return mixed
	 */
	public static function QueryOneRow($query, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
		return self::GetConnection($connection_tag)->queryOneRow($query);
	}
	
	/**
	 * Gets a single value from the first row of the query result. LIMIT must be specified in query if it's desired
	 * Returns null if the first row does not exist or the field name in the row does not exists
	 *
	 * @param string $query
	 * @param mixed $field_name If it's a number then fetchArray will be used instead of fetchRow
	 * @param string $connection_tag
	 * @return mixed
	 */
	public static function QueryOneValue($query, $field_name, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
		return self::GetConnection($connection_tag)->queryOneValue($query, $field_name);
	}
	/**
	 * Executes a query on the specified database
	 *
	 * @param string $query
	 * @param string $db
	 * @param string $connection_tag
	 * @return returns a link to the result set
	 */
	public static function QueryDb($query, $db, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		return self::GetConnection($connection_tag)->queryDb($query, $db);
	}
	/**
	 * Executes an insert query and reurns the id
	 *
	 * @param string $query
	 * @param string $connection_tag
	 * @return mixed the id of the inserted record
	 */
	public static function Insert($query, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		return self::GetConnection($connection_tag)->insert($query);
	}
	/**
	 * Fetches the row from a query result
	 *
	 * @param mixed $result
	 * @param string $connection_tag
	 * @return array Associative array (column => value)
	 */
	public static function FetchRow($result, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		return self::GetConnection($connection_tag)->fetchRow($result);
	}
	/**
	 * Fetches the row from a query result
	 *
	 * @param mixed $result
	 * @param string $connection_tag
	 * @return object 
	 */
	public static function FetchObject($result, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		return self::GetConnection($connection_tag)->fetchObject($result);
	}
	/**
	 * Counts the number of records resuled on a SELECT query
	 *
	 * @param mixed $result
	 * @param string $connection_tag
	 * @return integer
	 */
	public static function CountRows($result, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		return self::GetConnection($connection_tag)->CountRows($result);
	}
	/**
	 * Sets the current record in a recordset
	 *
	 * @param mixed $result
	 * @param integer $position
	 * @param string $connection_tag
	 */
	public static function SetCurrentRow($result, $position, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		self::GetConnection($connection_tag)->setCurrentRow($result, $position);
	}
	/**
	 * Gets the default charset for this connection
	 * 
	 * @param string $connection_tag
	 * @return string 
	 */
	public static function GetClientEncoding($connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		return self::GetConnection($connection_tag)->getClientEncoding();
	}
	/**
	 * Escapes a string for this connection
	 *
	 * @param string $str
	 * @param string $connection_tag
	 * @return string
	 */
	public static function EscapeString($str, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		return self::GetConnection($connection_tag)->escapeString($str);
	}
	/**
	 * Sets a database as the default for this connection
	 *
	 * @param string $db
	 * @param string $connection_tag
	 */
	public static function SelectDb($db, $connection_tag = self::DefaultTag)
	{
		if (!self::GetConnection($connection_tag))
			throw new Exception("No SQL connection defined for tag: $connection_tag");
			
		self::GetConnection($connection_tag)->selectDb($db);
	}
}

?>